﻿<script lang="ts" setup name="budgetDashboard">
import { ref, reactive, onMounted, onUnmounted, nextTick } from 'vue';
import { ElMessage } from 'element-plus';
import { Money, CircleCheck, Clock, Wallet, Calendar } from '@element-plus/icons-vue';
import * as echarts from 'echarts';
import { useStoreBudgetConfigApi, type BudgetDashboard, type BudgetSummary } from '/@/api/store/storeBudgetConfig';

const storeBudgetConfigApi = useStoreBudgetConfigApi();

// 数据状态
const loading = ref(false);
const autoRefresh = ref(true);
const refreshInterval = 30000; // 30秒
let refreshTimer: NodeJS.Timeout | null = null;

// 时间选择相关
const selectedDate = ref(new Date());
const isHistoryMode = ref(false);

// 仪表板数据
const dashboardData = reactive<BudgetDashboard>({
  summary: {
    totalBudgetCount: 0,
    totalAmount: 0,
    totalUsed: 0,
    totalPending: 0,
    totalRemaining: 0,
    overallUsageRate: 0,
    warningCount: 0,
    dangerCount: 0
  },
  budgetDetails: [],
  lastUpdateTime: ''
});


// 详情弹窗
const detailDialogVisible = ref(false);
const selectedBudget = ref<BudgetSummary | null>(null);

// 图表引用
const pieChartRef = ref<HTMLElement>();
const barChartRef = ref<HTMLElement>();
const ringProgressRef = ref<HTMLElement>();
const fundFlowRef = ref<HTMLElement>();
let pieChart: echarts.ECharts | null = null;
let barChart: echarts.ECharts | null = null;
let ringProgressChart: echarts.ECharts | null = null;
let fundFlowChart: echarts.ECharts | null = null;

// 组件挂载
onMounted(async () => {
  await loadData();
  await nextTick();
  initCharts();
  if (autoRefresh.value) {
    startAutoRefresh();
  }
  
  // 监听窗口大小变化
  window.addEventListener('resize', handleResize);
});

// 监听日期变化
const watchDate = () => {
  if (isHistoryMode.value) {
    autoRefresh.value = false;
    stopAutoRefresh();
  }
  loadData();
};

// 切换到历史模式
const switchToHistoryMode = () => {
  isHistoryMode.value = true;
  autoRefresh.value = false;
  stopAutoRefresh();
  ElMessage.info('已切换到历史数据模式');
};

// 切换到实时模式
const switchToLiveMode = () => {
  isHistoryMode.value = false;
  selectedDate.value = new Date();
  ElMessage.success('已切换到实时数据模式');
  loadData();
};

// 格式化选中日期显示
const formatSelectedDate = (date: any) => {
  if (!date) return '未选择';
  if (typeof date === 'string') {
    return new Date(date).toLocaleDateString('zh-CN');
  }
  if (date instanceof Date) {
    return date.toLocaleDateString('zh-CN');
  }
  return '未选择';
};

// 组件卸载
onUnmounted(() => {
  stopAutoRefresh();
  window.removeEventListener('resize', handleResize);
  if (pieChart) {
    pieChart.dispose();
  }
  if (barChart) {
    barChart.dispose();
  }
  if (ringProgressChart) {
    ringProgressChart.dispose();
  }
  if (fundFlowChart) {
    fundFlowChart.dispose();
  }
});

// 加载数据
const loadData = async () => {
  try {
    loading.value = true;
    
    // 根据历史模式决定传递的日期参数
    let targetDate = undefined;
    if (isHistoryMode.value && selectedDate.value) {
      // 处理日期，确保格式正确
      if (typeof selectedDate.value === 'string') {
        targetDate = selectedDate.value;
      } else if (selectedDate.value instanceof Date) {
        targetDate = selectedDate.value.toISOString().split('T')[0];
      }
    }
    
    // 先尝试加载基本数据（不依赖新API）
    try {
      // 加载仪表板数据
      const dashboardRes = await storeBudgetConfigApi.getDashboardData(targetDate);
      if (dashboardRes.data?.result) {
        Object.assign(dashboardData, dashboardRes.data.result);
      }
    } catch (dashboardError) {
      console.warn('看板数据加载失败，使用模拟数据:', dashboardError);
      // 使用模拟数据
      Object.assign(dashboardData, {
        summary: {
          totalBudgetCount: 0,
          totalAmount: 0,
          totalUsed: 0,
          totalPending: 0,
          totalRemaining: 0,
          overallUsageRate: 0,
          warningCount: 0,
          dangerCount: 0
        },
        budgetDetails: [],
        lastUpdateTime: new Date().toISOString()
      });
    }
    
    
    // 更新图表
    await nextTick();
    updateCharts();
    
  } catch (error) {
    console.error('加载数据失败:', error);
    ElMessage.error('加载数据失败，请检查网络连接');
  } finally {
    loading.value = false;
  }
};

// 刷新数据
const refreshData = async () => {
  await loadData();
};

// 自动刷新相关
const startAutoRefresh = () => {
  if (autoRefresh.value && !refreshTimer) {
    refreshTimer = setInterval(loadData, refreshInterval);
  }
};

const stopAutoRefresh = () => {
  if (refreshTimer) {
    clearInterval(refreshTimer);
    refreshTimer = null;
  }
};

const toggleAutoRefresh = () => {
  if (autoRefresh.value) {
    startAutoRefresh();
    ElMessage.success('已开启自动刷新');
  } else {
    stopAutoRefresh();
    ElMessage.info('已关闭自动刷新');
  }
};

// 显示预算详情
const showBudgetDetail = (budget: BudgetSummary) => {
  selectedBudget.value = budget;
  detailDialogVisible.value = true;
};

// 获取状态标签类型
const getStatusTagType = (status: string) => {
  switch (status) {
    case 'danger': return 'danger';
    case 'warning': return 'warning';
    default: return 'success';
  }
};

// 格式化货币
const formatCurrency = (amount: number) => {
  return new Intl.NumberFormat('zh-CN', {
    style: 'currency',
    currency: 'CNY',
    minimumFractionDigits: 0,
    maximumFractionDigits: 0,
  }).format(amount || 0);
};

// 格式化日期
const formatDate = (dateStr: string) => {
  return new Date(dateStr).toLocaleDateString('zh-CN');
};

// 格式化日期时间
const formatDateTime = (dateStr: string) => {
  if (!dateStr) return '';
  const date = new Date(dateStr);
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit', 
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  });
};

// 计算资金健康度
const calculateHealthScore = () => {
  const summary = dashboardData.summary;
  if (summary.totalAmount === 0) return { score: 0, level: 'danger', text: '无数据' };
  
  const remainingRate = (summary.totalRemaining / summary.totalAmount) * 100;
  const dangerRate = (summary.dangerCount / Math.max(summary.totalBudgetCount, 1)) * 100;
  const warningRate = (summary.warningCount / Math.max(summary.totalBudgetCount, 1)) * 100;
  
  let score = 100;
  
  // 根据剩余比例扣分
  if (remainingRate < 10) score -= 40;
  else if (remainingRate < 20) score -= 30;
  else if (remainingRate < 30) score -= 20;
  else if (remainingRate < 50) score -= 10;
  
  // 根据危险和预警比例扣分
  score -= dangerRate * 0.8;
  score -= warningRate * 0.4;
  
  score = Math.max(0, Math.min(100, score));
  
  let level: 'success' | 'warning' | 'danger';
  let text: string;
  
  if (score >= 80) {
    level = 'success';
    text = '健康';
  } else if (score >= 60) {
    level = 'warning';
    text = '预警';
  } else {
    level = 'danger';
    text = '风险';
  }
  
  return { score: Math.round(score), level, text };
};

// 计算预计耗尽时间
const calculateEstimatedDepleteTime = () => {
  const summary = dashboardData.summary;
  if (summary.totalRemaining <= 0) return '资金已耗尽';
  if (summary.totalUsed <= 0) return '暂无使用记录';
  
  // 这里简化计算，实际应该基于历史使用趋势
  const dailyUsage = summary.totalUsed / 30; // 假设当前使用量是30天的平均值
  if (dailyUsage <= 0) return '使用量为零';
  
  const remainingDays = Math.ceil(summary.totalRemaining / dailyUsage);
  
  if (remainingDays > 365) return '超过一年';
  if (remainingDays > 30) return `约${Math.ceil(remainingDays / 30)}个月`;
  return `约${remainingDays}天`;
};

// 窗口大小变化处理
const handleResize = () => {
  if (pieChart) {
    pieChart.resize();
  }
  if (barChart) {
    barChart.resize();
  }
  if (ringProgressChart) {
    ringProgressChart.resize();
  }
  if (fundFlowChart) {
    fundFlowChart.resize();
  }
};

// 初始化图表
const initCharts = () => {
  if (pieChartRef.value) {
    pieChart = echarts.init(pieChartRef.value);
  }
  if (barChartRef.value) {
    barChart = echarts.init(barChartRef.value);
  }
  if (ringProgressRef.value) {
    ringProgressChart = echarts.init(ringProgressRef.value);
  }
  if (fundFlowRef.value) {
    fundFlowChart = echarts.init(fundFlowRef.value);
  }
  updateCharts();
};

// 更新图表
const updateCharts = () => {
  updatePieChart();
  updateBarChart();
  updateRingProgressChart();
  updateFundFlowChart();
};

// 更新饼图
const updatePieChart = () => {
  if (!pieChart || !dashboardData.budgetDetails) return;
  
  const statusCount = {
    normal: 0,
    warning: 0,
    danger: 0
  };
  
  dashboardData.budgetDetails.forEach(budget => {
    statusCount[budget.status as keyof typeof statusCount]++;
  });
  
  const option = {
    tooltip: {
      trigger: 'item',
      formatter: '{a} <br/>{b}: {c} ({d}%)'
    },
    legend: {
      orient: 'vertical',
      left: 'left',
      data: ['正常', '预警', '超限']
    },
    series: [
      {
        name: '预算状态',
        type: 'pie',
        radius: '70%',
        center: ['60%', '50%'],
        data: [
          { value: statusCount.normal, name: '正常', itemStyle: { color: '#67C23A' } },
          { value: statusCount.warning, name: '预警', itemStyle: { color: '#E6A23C' } },
          { value: statusCount.danger, name: '超限', itemStyle: { color: '#F56C6C' } }
        ].filter(item => item.value > 0),
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: 'rgba(0, 0, 0, 0.5)'
          }
        }
      }
    ]
  };
  
  pieChart.setOption(option);
};

// 更新区域柱状图
const updateBarChart = () => {
  if (!barChart || !dashboardData.budgetDetails || dashboardData.budgetDetails.length === 0) return;
  
  // 按区域名称排序
  const sortedBudgets = [...dashboardData.budgetDetails].sort((a, b) => a.orgName.localeCompare(b.orgName));
  
  const orgNames = sortedBudgets.map(budget => budget.orgName);
  const totalAmounts = sortedBudgets.map(budget => budget.totalAmount);
  const usedAmounts = sortedBudgets.map(budget => budget.usedAmount);
  const pendingAmounts = sortedBudgets.map(budget => budget.pendingAmount);
  const remainingAmounts = sortedBudgets.map(budget => budget.remainingAmount);
  
  const option = {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      },
      formatter: function(params: any) {
        let result = `${params[0].axisValue}<br/>`;
        params.forEach((item: any) => {
          const value = item.value >= 10000 ? (item.value / 10000).toFixed(1) + '万' : item.value.toLocaleString();
          result += `${item.marker}${item.seriesName}: ¥${value}<br/>`;
        });
        return result;
      }
    },
    legend: {
      data: ['总预算', '已使用', '申请中', '剩余'],
      top: 10
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '25%',
      top: '15%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: orgNames,
      axisLabel: {
        rotate: 45,
        interval: 0,
        fontSize: 12
      }
    },
    yAxis: {
      type: 'value',
      axisLabel: {
        formatter: (value: number) => {
          if (value >= 10000) {
            return (value / 10000).toFixed(1) + '万';
          }
          return value.toString();
        }
      }
    },
    series: [
      {
        name: '总预算',
        type: 'bar',
        data: totalAmounts,
        itemStyle: {
          color: '#409EFF'
        }
      },
      {
        name: '已使用',
        type: 'bar',
        data: usedAmounts,
        itemStyle: {
          color: '#67C23A'
        }
      },
      {
        name: '申请中',
        type: 'bar',
        data: pendingAmounts,
        itemStyle: {
          color: '#E6A23C'
        }
      },
      {
        name: '剩余',
        type: 'bar',
        data: remainingAmounts,
        itemStyle: {
          color: '#909399'
        }
      }
    ]
  };
  
  barChart.setOption(option);
};

// 更新矩形树图
const updateRingProgressChart = () => {
  if (!ringProgressChart) return;
  
  const summary = dashboardData.summary;
  
  // 确保数据有效性
  const totalAmount = summary.totalAmount || 1000000;
  const totalRemaining = summary.totalRemaining || 0;
  const totalUsed = summary.totalUsed || 0;
  const totalPending = summary.totalPending || 0;
  
  const option = {
    title: {
      text: '资金分布矩形树图',
      subtext: `总预算: ${formatCurrency(totalAmount)}`,
      left: 'center',
      top: 15,
      textStyle: {
        fontSize: 14,
        fontWeight: 'bold',
        color: '#303133'
      },
      subtextStyle: {
        fontSize: 12,
        color: '#666'
      }
    },
    tooltip: {
      trigger: 'item',
      formatter: function(params: any) {
        const percentage = ((params.data.value / totalAmount) * 100).toFixed(1);
        return `${params.data.name}<br/>金额: ${formatCurrency(params.data.value)}<br/>占比: ${percentage}%`;
      }
    },
    series: [{
      name: '资金分布',
      type: 'treemap',
      top: '25%',
      left: '8%',
      right: '8%',
      bottom: '8%',
      roam: false,
      nodeClick: false,
      breadcrumb: {
        show: false
      },
      data: [
        {
          name: '剩余可用',
          value: totalRemaining,
          itemStyle: {
            color: '#67C23A',
            borderColor: '#fff',
            borderWidth: 2
          },
          label: {
            show: true,
            position: 'inside',
            formatter: '💚 剩余可用\n{c}',
            fontSize: 12,
            fontWeight: 'bold',
            color: '#fff'
          }
        },
        {
          name: '已使用',
          value: totalUsed,
          itemStyle: {
            color: '#F56C6C',
            borderColor: '#fff',
            borderWidth: 2
          },
          label: {
            show: true,
            position: 'inside',
            formatter: '🔥 已使用\n{c}',
            fontSize: 12,
            fontWeight: 'bold',
            color: '#fff'
          }
        },
        {
          name: '申请中',
          value: totalPending,
          itemStyle: {
            color: '#E6A23C',
            borderColor: '#fff',
            borderWidth: 2
          },
          label: {
            show: true,
            position: 'inside',
            formatter: '⏳ 申请中\n{c}',
            fontSize: 12,
            fontWeight: 'bold',
            color: '#fff'
          }
        }
      ],
      label: {
        show: true,
        position: 'inside',
        formatter: function(params: any) {
          const percentage = ((params.value / totalAmount) * 100).toFixed(1);
          return `${params.name}\n${formatCurrency(params.value)}\n${percentage}%`;
        },
        fontSize: 11,
        fontWeight: 'bold',
        color: '#fff'
      },
      itemStyle: {
        borderColor: '#fff',
        borderWidth: 3,
        gapWidth: 3
      },
      emphasis: {
        itemStyle: {
          shadowBlur: 15,
          shadowColor: 'rgba(0, 0, 0, 0.3)',
          borderWidth: 4
        },
        label: {
          fontSize: 13
        }
      }
    }]
  };
  
  try {
    ringProgressChart.setOption(option, true);
    console.log('矩形树图设置成功');
  } catch (error) {
    console.error('矩形树图设置失败:', error);
    // 如果treemap失败，降级使用饼图
    const fallbackOption = {
      title: {
        text: '资金分布',
        left: 'center',
        top: 15
      },
      tooltip: {
        trigger: 'item',
        formatter: '{a} <br/>{b}: {c} ({d}%)'
      },
      series: [{
        name: '资金分布',
        type: 'pie',
        radius: '60%',
        center: ['50%', '60%'],
        data: [
          { value: totalRemaining, name: '剩余可用', itemStyle: { color: '#67C23A' } },
          { value: totalUsed, name: '已使用', itemStyle: { color: '#F56C6C' } },
          { value: totalPending, name: '申请中', itemStyle: { color: '#E6A23C' } }
        ]
      }]
    };
    ringProgressChart.setOption(fallbackOption, true);
  }
};

// 更新资金流向图
const updateFundFlowChart = () => {
  if (!fundFlowChart) return;
  
  const summary = dashboardData.summary;
  
  const option = {
    title: {
      text: '资金分布概览',
      left: 'center',
      top: 10,
      textStyle: {
        fontSize: 14,
        color: '#606266'
      }
    },
    tooltip: {
      trigger: 'item',
      formatter: function(params: any) {
        return `${params.name}: ${formatCurrency(params.value)}`;
      }
    },
    grid: {
      left: '10%',
      right: '10%',
      top: '20%',
      bottom: '10%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      data: ['总预算', '资金使用情况'],
      axisLabel: {
        fontSize: 12,
        color: '#606266'
      },
      axisLine: {
        lineStyle: {
          color: '#DCDFE6'
        }
      }
    },
    yAxis: {
      type: 'value',
      axisLabel: {
        formatter: (value: number) => {
          if (value >= 10000) {
            return (value / 10000).toFixed(1) + '万';
          }
          return value.toString();
        },
        fontSize: 12,
        color: '#606266'
      },
      axisLine: {
        show: false
      },
      splitLine: {
        lineStyle: {
          color: '#F2F6FC'
        }
      }
    },
    series: [
      {
        name: '总预算',
        type: 'bar',
        data: [summary.totalAmount, null],
        barWidth: '60%', // 从40%增加到60%
        itemStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: '#409EFF' },
            { offset: 1, color: '#E1F0FF' }
          ]),
          borderRadius: [4, 4, 0, 0]
        },
        label: {
          show: true,
          position: 'top',
          formatter: function(params: any) {
            return formatCurrency(params.value);
          },
          fontSize: 11,
          color: '#409EFF',
          fontWeight: 'bold'
        }
      },
      {
        name: '已使用',
        type: 'bar',
        stack: 'usage',
        data: [null, summary.totalUsed],
        itemStyle: {
          color: '#F56C6C'
        },
        barWidth: '60%' // 从40%增加到60%
      },
      {
        name: '申请中',
        type: 'bar',
        stack: 'usage',
        data: [null, summary.totalPending],
        itemStyle: {
          color: '#E6A23C'
        }
      },
      {
        name: '剩余',
        type: 'bar',
        stack: 'usage',
        data: [null, summary.totalRemaining],
        itemStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: '#67C23A' },
            { offset: 1, color: '#C2E7B0' }
          ])
        },
        label: {
          show: true,
          position: 'top',
          formatter: function() {
            return `剩余: ${formatCurrency(summary.totalRemaining)}`;
          },
          fontSize: 11,
          color: '#67C23A',
          fontWeight: 'bold'
        }
      }
    ]
  };
  
  fundFlowChart.setOption(option, true);
};
</script>

<template>
  <div class="budget-dashboard">
    <!-- 时间选择器 -->
    <el-row class="time-selector-row" style="margin-bottom: 20px;">
      <el-col :span="24">
        <el-card :body-style="{ padding: '15px' }">
          <div class="time-selector">
            <div class="selector-left">
              <el-radio-group v-model="isHistoryMode" @change="isHistoryMode ? switchToHistoryMode() : switchToLiveMode()">
                <el-radio-button :label="false">实时数据</el-radio-button>
                <el-radio-button :label="true">历史数据</el-radio-button>
              </el-radio-group>
            </div>
            <div class="selector-right" v-if="isHistoryMode">
              <el-date-picker
                v-model="selectedDate"
                type="date"
                placeholder="选择日期"
                format="YYYY-MM-DD"
                value-format="YYYY-MM-DD"
                @change="watchDate"
                style="margin-left: 15px;"
                clearable
              />
              <el-button 
                type="primary" 
                size="small" 
                @click="watchDate" 
                :loading="loading"
                style="margin-left: 10px;"
              >
                查询
              </el-button>
            </div>
            <div class="selector-info">
              <span class="info-text">
                <el-icon><Calendar /></el-icon>
                {{ isHistoryMode ? `查看历史: ${formatSelectedDate(selectedDate)}` : '实时数据模式' }}
              </span>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 总览卡片 -->
    <el-row :gutter="20" class="summary-cards" type="flex" align="top">
      <el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
        <el-card class="summary-card total-budget">
          <div class="card-content">
            <div class="card-icon">
              <el-icon size="40" color="#409EFF"><Money /></el-icon>
            </div>
            <div class="card-info">
              <div class="card-value">{{ formatCurrency(dashboardData.summary.totalAmount) }}</div>
              <div class="card-label">总预算额度</div>
              <div class="card-count">{{ dashboardData.summary.totalBudgetCount }} 个预算</div>
            </div>
          </div>
        </el-card>
      </el-col>
      
      <el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
        <el-card class="summary-card remaining-budget-highlight">
          <div class="card-content">
            <div class="card-icon">
              <el-icon size="40" color="#409EFF"><Wallet /></el-icon>
            </div>
            <div class="card-info">
              <div class="card-value highlighted">{{ formatCurrency(dashboardData.summary.totalRemaining) }}</div>
              <div class="card-label">剩余可用额度</div>
              <div class="card-count">{{ ((dashboardData.summary.totalRemaining / Math.max(dashboardData.summary.totalAmount, 1)) * 100).toFixed(1) }}% 可用</div>
            </div>
          </div>
        </el-card>
      </el-col>
      
      <el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
        <el-card class="summary-card health-score" :class="`health-${calculateHealthScore().level}`">
          <div class="card-content">
            <div class="card-icon">
              <div class="health-circle">
                <span class="health-score-text">{{ calculateHealthScore().score }}</span>
              </div>
            </div>
            <div class="card-info">
              <div class="card-value">{{ calculateHealthScore().text }}</div>
              <div class="card-label">资金健康度</div>
              <div class="card-count">综合评分</div>
            </div>
          </div>
        </el-card>
      </el-col>
      
      <el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6">
        <el-card class="summary-card estimated-time">
          <div class="card-content">
            <div class="card-icon">
              <el-icon size="40" color="#E6A23C"><Clock /></el-icon>
            </div>
            <div class="card-info">
              <div class="card-value">{{ calculateEstimatedDepleteTime() }}</div>
              <div class="card-label">预计可用时长</div>
              <div class="card-count">基于当前使用速度</div>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 预警和配置信息 -->
    <el-row :gutter="20">
      <el-col :span="24" v-if="dashboardData.summary.warningCount > 0 || dashboardData.summary.dangerCount > 0">
        <el-alert
          :title="`预警提醒：${dashboardData.summary.dangerCount} 个预算超限，${dashboardData.summary.warningCount} 个预算预警`"
          type="warning"
          :description="`请及时关注预算使用情况，避免超支风险`"
          show-icon
          :closable="false">
        </el-alert>
      </el-col>
      <el-col :span="24" v-if="dashboardData.budgetDetails.length > 0">
        <el-card class="config-info-card" :body-style="{ padding: '12px' }">
          <div class="config-info">
            <span class="config-label">
              <el-icon><Calendar /></el-icon>
              当前预算配置：
            </span>
            <span class="config-details">
              基于精准时间段匹配，共 {{ dashboardData.summary.totalBudgetCount }} 个区域有效预算
              {{ isHistoryMode ? '（历史数据）' : '' }}
            </span>
            <span class="config-time">
              数据更新时间：{{ formatDateTime(dashboardData.lastUpdateTime) }}
              {{ dashboardData.queryDate ? ` | 查询日期：${formatDate(dashboardData.queryDate)}` : '' }}
            </span>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 核心资金图表区域 -->
    <el-row :gutter="20">
      <!-- 矩形树图 -->
      <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
        <el-card class="chart-card ring-chart-card">
          <template #header>
            <div class="chart-title">
              <span>🗂️ 资金分布矩形树图</span>
              <span class="chart-subtitle">面积大小直观反映金额比例</span>
            </div>
          </template>
          <div ref="ringProgressRef" class="ring-progress-chart"></div>
        </el-card>
      </el-col>
      
      <!-- 资金对比图 -->
      <el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="6">
        <el-card class="chart-card fund-flow-card">
          <template #header>
            <div class="chart-title">
              <span>📊 总额 vs 剩余对比</span>
              <span class="chart-subtitle">预算使用情况对比</span>
            </div>
          </template>
          <div ref="fundFlowRef" class="fund-flow-chart"></div>
        </el-card>
      </el-col>
      
      <!-- 状态分布图 -->
      <el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="6">
        <el-card class="chart-card status-chart-card">
          <template #header>
            <div class="chart-title">
              <span>📈 预算状态分布</span>
              <span class="chart-subtitle">各区域健康状况</span>
            </div>
          </template>
          <div ref="pieChartRef" class="pie-chart"></div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 主要内容区域 -->
    <el-row :gutter="20">
      <!-- 左侧：区域预算列表 -->
      <el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="16">
        <el-card class="budget-list-card">
          <template #header>
            <div class="card-header">
              <span>区域预算使用情况</span>
              <div class="header-actions">
                <el-button size="small" @click="refreshData" :loading="loading" icon="Refresh">刷新</el-button>
                <el-switch
                  v-model="autoRefresh"
                  @change="toggleAutoRefresh"
                  active-text="自动刷新"
                  inactive-text="手动刷新"
                  size="small"
                  :disabled="isHistoryMode"
                />
              </div>
            </div>
          </template>
          
          <div class="budget-items">
            <div 
              v-for="budget in dashboardData.budgetDetails" 
              :key="budget.id" 
              class="budget-item"
              :class="`budget-${budget.status}`"
              @click="showBudgetDetail(budget)"
            >
              <div class="budget-header">
                <div class="budget-org">
                  <el-tag :type="getStatusTagType(budget.status)" size="small">
                    {{ budget.status === 'normal' ? '正常' : budget.status === 'warning' ? '预警' : '超限' }}
                  </el-tag>
                  <span class="org-name">{{ budget.orgName }}</span>
                </div>
                <div class="budget-meta">
                  <div class="budget-name">{{ budget.budgetName || '预算配置' }}</div>
                  <div class="budget-period">
                    {{ formatDate(budget.startDate) }} ~ {{ formatDate(budget.endDate) }}
                  </div>
                </div>
              </div>
              
              <div class="budget-progress">
                <div class="progress-info">
                  <span class="progress-label">资金使用进度</span>
                  <span class="progress-percent">{{ budget.usageRate.toFixed(1) }}%</span>
                </div>
                
                <!-- 分段进度条 -->
                <div class="multi-progress-container">
                  <div class="multi-progress-bar">
                    <!-- 已使用部分 -->
                    <div 
                      class="progress-segment used-segment"
                      :style="{ width: Math.min((budget.usedAmount / budget.totalAmount * 100), 100) + '%' }"
                      :title="`已使用: ${formatCurrency(budget.usedAmount)}`"
                    ></div>
                    <!-- 申请中部分 -->
                    <div 
                      class="progress-segment pending-segment"
                      :style="{ 
                        width: Math.min((budget.pendingAmount / budget.totalAmount * 100), 100 - (budget.usedAmount / budget.totalAmount * 100)) + '%',
                        left: Math.min((budget.usedAmount / budget.totalAmount * 100), 100) + '%'
                      }"
                      :title="`申请中: ${formatCurrency(budget.pendingAmount)}`"
                    ></div>
                  </div>
                  
                  <!-- 进度条图例 -->
                  <div class="progress-legend">
                    <div class="legend-item">
                      <span class="legend-color used-color"></span>
                      <span class="legend-text">已使用</span>
                    </div>
                    <div class="legend-item">
                      <span class="legend-color pending-color"></span>
                      <span class="legend-text">申请中</span>
                    </div>
                    <div class="legend-item">
                      <span class="legend-color remaining-color"></span>
                      <span class="legend-text">剩余</span>
                    </div>
                  </div>
                </div>
              </div>
              
              <div class="budget-amounts">
                <div class="amount-item">
                  <span class="amount-label">总额度</span>
                  <span class="amount-value">{{ formatCurrency(budget.totalAmount) }}</span>
                </div>
                <div class="amount-item">
                  <span class="amount-label">已使用</span>
                  <span class="amount-value used">{{ formatCurrency(budget.usedAmount) }}</span>
                </div>
                <div class="amount-item">
                  <span class="amount-label">申请中</span>
                  <span class="amount-value pending">{{ formatCurrency(budget.pendingAmount) }}</span>
                </div>
                <div class="amount-item">
                  <span class="amount-label">剩余</span>
                  <span class="amount-value remaining">{{ formatCurrency(budget.remainingAmount) }}</span>
                </div>
              </div>
            </div>
          </div>
        </el-card>
      </el-col>
      
      <!-- 右侧：区域对比图表 -->
      <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
        <el-card class="chart-card bar-card">
          <template #header>
            <span>🏢 各区域预算对比</span>
          </template>
          <div ref="barChartRef" class="bar-chart"></div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 详情弹窗 -->
    <el-dialog
      v-model="detailDialogVisible"
      :title="`${selectedBudget?.orgName} - ${selectedBudget?.budgetName || '预算详情'}`"
      width="600px"
    >
      <div v-if="selectedBudget" class="budget-detail">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="区域名称">{{ selectedBudget.orgName }}</el-descriptions-item>
          <el-descriptions-item label="预算名称">{{ selectedBudget.budgetName || '-' }}</el-descriptions-item>
          <el-descriptions-item label="预算期间">
            {{ formatDate(selectedBudget.startDate) }} ~ {{ formatDate(selectedBudget.endDate) }}
          </el-descriptions-item>
          <el-descriptions-item label="预算状态">
            <el-tag :type="getStatusTagType(selectedBudget.status)">
              {{ selectedBudget.status === 'normal' ? '正常' : selectedBudget.status === 'warning' ? '预警' : '超限' }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="总预算额度">{{ formatCurrency(selectedBudget.totalAmount) }}</el-descriptions-item>
          <el-descriptions-item label="已使用额度">{{ formatCurrency(selectedBudget.usedAmount) }}</el-descriptions-item>
          <el-descriptions-item label="申请中额度">{{ formatCurrency(selectedBudget.pendingAmount) }}</el-descriptions-item>
          <el-descriptions-item label="剩余额度">{{ formatCurrency(selectedBudget.remainingAmount) }}</el-descriptions-item>
          <el-descriptions-item label="使用率">{{ selectedBudget.usageRate.toFixed(1) }}%</el-descriptions-item>
          <el-descriptions-item label="预警阈值">{{ selectedBudget.warningThreshold }}%</el-descriptions-item>
          <el-descriptions-item label="预警开关">
            <el-tag :type="selectedBudget.isWarningEnabled ? 'success' : 'info'">
              {{ selectedBudget.isWarningEnabled ? '已开启' : '已关闭' }}
            </el-tag>
          </el-descriptions-item>
        </el-descriptions>
      </div>
    </el-dialog>
  </div>
</template>

<style scoped>
.budget-dashboard {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: calc(100vh - 100px);
}

/* 统一所有section之间的间距 */
.budget-dashboard .el-row {
  margin-bottom: 0;
}

.budget-dashboard .el-row + .el-row {
  margin-top: 20px;
}

/* 处理同一行内多个col之间的间距 */
.budget-dashboard .el-col + .el-col {
  margin-top: 20px;
}

/* 但是水平排列的col不需要上边距 */
.budget-dashboard .el-row:not(.summary-cards) .el-col + .el-col {
  margin-top: 0;
}

/* 特别重置summary-cards的col样式 */
.budget-dashboard .summary-cards .el-col + .el-col {
  margin-top: 0 !important;
}

/* 确保summary-cards行的所有列都对齐 */
.summary-cards {
  align-items: flex-start !important; /* 顶部对齐 */
}

.summary-cards .el-col {
  display: flex !important;
  align-items: stretch !important; /* 拉伸到相同高度 */
  margin-top: 0 !important; /* 清除顶部边距 */
  margin-bottom: 0 !important; /* 清除底部边距 */
  padding-top: 0 !important; /* 清除顶部内边距 */
  padding-bottom: 0 !important; /* 清除底部内边距 */
}

.summary-cards .summary-card {
  border-radius: 8px;
  overflow: hidden;
  transition: transform 0.3s ease;
  height: 120px !important; /* 强制固定高度确保对齐 */
  max-height: 120px !important; /* 防止超出 */
  width: 100% !important; /* 占满列宽 */
  margin: 0 !important; /* 清除任何外边距 */
  vertical-align: top !important; /* 顶部对齐 */
}

.summary-cards .el-card {
  height: 100% !important;
  max-height: 120px !important;
}

/* 确保所有卡片的body样式一致 */
.summary-cards .el-card__body {
  height: 100% !important;
  max-height: 120px !important;
  padding: 0 !important; /* 移除默认padding，使用card-content的padding */
  overflow: hidden !important; /* 防止内容溢出 */
}

.summary-cards .summary-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}

.card-content {
  display: flex;
  align-items: center;
  padding: 15px !important; /* 强制统一内边距 */
  height: 120px !important; /* 强制固定高度 */
  max-height: 120px !important; /* 防止超出 */
  box-sizing: border-box !important; /* 确保padding计算方式一致 */
  overflow: hidden !important; /* 防止内容溢出 */
}

.card-icon {
  margin-right: 15px;
  opacity: 0.8;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0; /* 防止收缩 */
}

.card-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center; /* 垂直居中 */
  height: 90px !important; /* 固定高度，减去padding(15px*2=30px) */
  max-height: 90px !important;
  overflow: hidden !important;
}

.card-value {
  font-size: 24px !important; /* 强制统一字体大小 */
  font-weight: bold;
  line-height: 1.2; /* 统一行高 */
  margin-bottom: 5px;
}

.card-label {
  font-size: 14px;
  color: #666;
  margin-bottom: 3px;
}

.card-count, .card-rate {
  font-size: 12px;
  color: #999;
}

.total-budget {
  border-left: 4px solid #409EFF;
  height: 120px !important; /* 强制高度一致 */
  max-height: 120px !important;
}

.used-budget {
  border-left: 4px solid #67C23A;
}

.pending-budget {
  border-left: 4px solid #E6A23C;
}

.remaining-budget {
  border-left: 4px solid #909399;
}

.remaining-budget-highlight {
  border-left: 4px solid #409EFF;
  background: linear-gradient(135deg, #409EFF 0%, #79BBF5 100%);
  color: white;
  height: 120px !important; /* 强制高度一致 */
  max-height: 120px !important;
}

.remaining-budget-highlight .card-label,
.remaining-budget-highlight .card-count {
  color: rgba(255, 255, 255, 0.9);
}

.remaining-budget-highlight .card-value.highlighted {
  /* 字体大小已统一通过 .card-value 设置 */
  font-weight: bold;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.health-score {
  border-left: 4px solid #67C23A;
  height: 120px !important; /* 强制高度一致 */
  max-height: 120px !important;
}

.health-success {
  border-left-color: #67C23A;
}

.health-warning {
  border-left-color: #E6A23C;
}

.health-danger {
  border-left-color: #F56C6C;
}

.health-circle {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  color: white;
  background: linear-gradient(135deg, #67C23A 0%, #85CE61 100%);
  flex-shrink: 0; /* 防止收缩 */
}

.health-warning .health-circle {
  background: linear-gradient(135deg, #E6A23C 0%, #EEBE77 100%);
}

.health-danger .health-circle {
  background: linear-gradient(135deg, #F56C6C 0%, #F78989 100%);
}

.health-score-text {
  font-size: 16px;
}

.estimated-time {
  border-left: 4px solid #E6A23C;
  height: 120px !important; /* 强制高度一致 */
  max-height: 120px !important;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.budget-list-card {
  min-height: 600px;
}

.budget-items {
  max-height: 550px;
  overflow-y: auto;
}

.budget-item {
  padding: 16px;
  margin-bottom: 12px;
  border-radius: 8px;
  border: 1px solid #ebeef5;
  background: #fff;
  cursor: pointer;
  transition: all 0.3s ease;
}

.budget-item:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
}

.budget-normal {
  border-left: 4px solid #67C23A;
}

.budget-warning {
  border-left: 4px solid #E6A23C;
}

.budget-danger {
  border-left: 4px solid #F56C6C;
}

.budget-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.budget-org {
  display: flex;
  align-items: center;
  gap: 8px;
}

.org-name {
  font-weight: bold;
  color: #303133;
}

.budget-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
}

.budget-name {
  color: #303133;
  font-size: 12px;
  font-weight: 500;
  margin-bottom: 2px;
}

.budget-period {
  color: #909399;
  font-size: 10px;
}

.budget-progress {
  margin-bottom: 15px;
}

.progress-info {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
}

.progress-label {
  font-size: 14px;
  color: #606266;
}

.progress-percent {
  font-weight: bold;
  font-size: 14px;
}

.multi-progress-container {
  margin-top: 8px;
}

.multi-progress-bar {
  position: relative;
  height: 12px;
  background-color: #f5f7fa;
  border-radius: 6px;
  overflow: hidden;
  margin-bottom: 8px;
}

.progress-segment {
  position: absolute;
  top: 0;
  height: 100%;
  transition: all 0.3s ease;
}

.used-segment {
  background: linear-gradient(90deg, #67C23A 0%, #85CE61 100%);
  border-radius: 6px 0 0 6px;
}

.pending-segment {
  background: linear-gradient(90deg, #E6A23C 0%, #EEBE77 100%);
}

.progress-legend {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 11px;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 4px;
}

.legend-color {
  width: 12px;
  height: 8px;
  border-radius: 2px;
}

.used-color {
  background: linear-gradient(90deg, #67C23A 0%, #85CE61 100%);
}

.pending-color {
  background: linear-gradient(90deg, #E6A23C 0%, #EEBE77 100%);
}

.remaining-color {
  background: linear-gradient(90deg, #909399 0%, #C8C9CC 100%);
}

.legend-text {
  color: #606266;
  font-size: 11px;
}

.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
}

.header-summary {
  font-size: 12px;
  color: #909399;
}

.summary-text {
  font-weight: 500;
}

.fund-details {
  padding: 10px 15px;
  background: #f8f9fa;
  border-radius: 8px;
  margin-top: 10px;
}

.detail-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 0;
  border-bottom: 1px solid #ebeef5;
}

.detail-row:last-child {
  border-bottom: none;
}

.detail-row.highlight {
  background: linear-gradient(90deg, rgba(64, 158, 255, 0.05) 0%, rgba(121, 187, 245, 0.05) 100%);
  border-radius: 6px;
  padding: 8px 10px;
  margin: 4px 0;
  border: 1px solid rgba(64, 158, 255, 0.2);
}

.detail-label {
  font-size: 13px;
  color: #606266;
  font-weight: 500;
}

.detail-value {
  font-size: 13px;
  font-weight: bold;
}

.detail-value.used {
  color: #67C23A;
}

.detail-value.pending {
  color: #E6A23C;
}

.detail-value.remaining {
  color: #409EFF;
  font-size: 14px;
}


.chart-title {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.chart-subtitle {
  font-size: 11px;
  color: #909399;
  font-weight: normal;
}

.status-chart-card {
  height: 380px; /* 增加100px高度 */
}

.budget-amounts {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

.amount-item {
  display: flex;
  justify-content: space-between;
  padding: 8px;
  background: #f5f7fa;
  border-radius: 4px;
}

.amount-label {
  font-size: 12px;
  color: #909399;
}

.amount-value {
  font-size: 12px;
  font-weight: bold;
}

.amount-value.used {
  color: #67C23A;
}

.amount-value.pending {
  color: #E6A23C;
}

.amount-value.remaining {
  color: #409EFF;
}

.chart-card {
  height: 380px; /* 增加100px高度 */
}

.ring-chart-card {
  height: 380px; /* 增加100px高度 */
}

.fund-flow-card {
  height: 380px; /* 增加100px高度 */
}

.bar-card {
  height: 580px;
}

.pie-chart {
  width: 100%;
  height: 320px; /* 增加100px高度 */
}

.ring-progress-chart {
  width: 100%;
  height: 320px; /* 增加100px高度 */
}

.fund-flow-chart {
  width: 100%;
  height: 320px; /* 增加100px高度 */
}

.bar-chart {
  width: 100%;
  height: 520px;
}

.budget-detail {
  padding: 10px 0;
}

.config-info-card {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
  color: white;
}

.config-info {
  display: flex;
  align-items: center;
  gap: 15px;
  font-size: 13px;
}

.config-label {
  display: flex;
  align-items: center;
  gap: 5px;
  font-weight: 600;
  color: #fff;
}

.config-details {
  flex: 1;
  color: #e8f4fd;
}

.config-time {
  color: #bfdbfe;
  font-size: 12px;
}

.time-selector {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 15px;
}

.selector-left {
  display: flex;
  align-items: center;
}

.selector-right {
  display: flex;
  align-items: center;
}

.selector-info {
  display: flex;
  align-items: center;
  color: #606266;
  font-size: 14px;
}

.info-text {
  display: flex;
  align-items: center;
  gap: 5px;
}

@media (max-width: 768px) {
  .time-selector {
    flex-direction: column;
    align-items: flex-start;
  }
  
  .selector-right {
    margin-top: 10px;
  }
}

@media (max-width: 768px) {
  .budget-dashboard {
    padding: 10px;
  }
  
  .budget-amounts {
    grid-template-columns: 1fr;
  }
  
  .card-content {
    flex-direction: column;
    text-align: center;
  }
  
  .card-icon {
    margin-right: 0;
    margin-bottom: 10px;
  }
}
</style>